package com.better517na.stateprocess.run;

import com.better517na.stateprocess.annotion.OrderProcessor;
import com.better517na.stateprocess.model.common.OrderEventEnum;
import com.better517na.stateprocess.model.common.OrderSceneEnum;
import com.better517na.stateprocess.model.common.OrderStatusEnum;
import com.better517na.stateprocess.model.common.OrderTypeEnum;
import com.better517na.stateprocess.state.StateProcessor;
import com.better517na.stateprocess.state.impl.AbstractStateProcessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

@Component("defaultStateProcessRegistry")
public class DefaultStateProcessRegistry implements BeanPostProcessor {
    /**
     *  第一层key是订单场景 + 订单类型 + 订单状态
     *  第二层key是具体的事件
     *  彤彤一个
     * */
    private static Map<String, Map<String, List<AbstractStateProcessor>>> stateProcessMap = new ConcurrentHashMap<>();
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof AbstractStateProcessor && bean.getClass().isAnnotationPresent(OrderProcessor.class)) {
            OrderProcessor annotation = bean.getClass().getAnnotation(OrderProcessor.class);
            OrderEventEnum[] events = annotation.event();
            OrderStatusEnum[] states = annotation.state();
            OrderSceneEnum[] orderScenes = annotation.orderScene();
            OrderTypeEnum[] orderTypes = annotation.orderType();
            //初始化每个事件下不同的类
            initProcessMap(states, events, orderScenes, orderTypes, stateProcessMap, (AbstractStateProcessor) bean);
        }
        return bean;
    }
    private <E extends StateProcessor> void initProcessMap(OrderStatusEnum[] states, OrderEventEnum[] events, OrderSceneEnum[] orderScenes,OrderTypeEnum[] orderTypes
            , Map<String, Map<String, List<E>>> map, E processor) {
        for (OrderSceneEnum orderScene : orderScenes) {
            for (OrderTypeEnum orderType : orderTypes) {
                for (OrderStatusEnum state : states) {
                    Arrays.asList(events).parallelStream().forEach(p -> {
                        registerStateHandlers(state.getStatus(), p.getCode(), orderScene.getOrderScene(), orderType.getOrderType(), map, processor);
                    });
                }
            }
        }
    }
    /**     * 初始化状态机处理器     */
    public <E extends StateProcessor> void registerStateHandlers(String orderState, String event, String orderScene, String orderType, Map<String, Map<String, List<E>>> map, E processor) {
        // 第一层状态维度
        String key =  orderScene + "@" + orderType + "@" + orderState;
        if (!map.containsKey(key)) {
            map.put(orderState, new ConcurrentHashMap<>());
        }

        Map<String, List<E>> processorMap = map.get(key);
        // event维度
        if (!processorMap.containsKey(event)) {
            processorMap.put(event, new ArrayList<>());
        }

        processorMap.get(event).add(processor);
    }

    public List<AbstractStateProcessor> acquireStateProcess(String orderState, String event, String orderScene, String orderType) {
        if(!stateProcessMap.isEmpty()){
            String key = orderScene + "@" + orderType + "@" + orderState;
            if(stateProcessMap.containsKey(key)){
                Map<String, List<AbstractStateProcessor>> eventMap = stateProcessMap.get(key);
                if(eventMap.containsKey(event)){
                    return eventMap.get(event);
                }
            }
        }

        return null;
    }
}
